package com.rem.cloudalibaba.service;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Map;

/**
 * @author Rem
 * @date 2021/12/4
 * restful 接口定义原则
 * <p>
 * 定义一个本地接口。用于做远程方法调用标准定义的。
 * spring环境会根据当前接口中的注解，动态生成代理对象，实现远程服务调用。
 * 远程服务调用基于HTTP协议。
 * <p>
 * http://服务名称/路径地址?参数
 * FeignClient - 当前接口是一个OpenFeign技术需要处理的本地接口。
 * value属性 - 当前接口对应的远程服务命名是什么。
 * 可以在执行远程访问的时候，生成URI， http://value
 */

public interface RemoteInterface {
    /**
     * RESTFul参数
     * 在OpenFeign中，描述RESTFul参数的时候，注解PathVariable属性value必须提供。
     * 不提供属性value，异常信息：PathVariable annotation was empty on param 0.
     */
    @GetMapping("/testRestParams/{name}/{age}")
    String restfulArgs(@PathVariable("name") String name, @PathVariable("age") int age);

    /**
     * 请求体参数
     * 如果请求参数通过请求体传递，且请求头content-type是application/json。
     * 方法参数可以不提供任何注解描述。
     * 强制要求，参数必须只有一个无注解描述。
     * 建议： 如果方法参数表有多个参数时，请求体参数使用@RequestBody描述参数。
     * <p>
     * 开发习惯例外： 如果方法只有唯一参数的时候，不推荐写注解。
     */
    @PostMapping("/postBodyArgs")
    String postBodyArgs(Map<String, Object> params);

    /**
     * 请求参数处理
     * 方法参数就是请求参数。
     * 如果没有任何特殊定义。参数是请求体参数，请求头content-type是application/json。
     * 强制要求：
     * 1、 只能有唯一的一个参数不做任何处理。无注解描述
     * 建议：
     * 1、 这种请求体参数，最好定义在方法参数表中的最后一个。
     * 2、 这种请求体参数，最好使用@RequestBody注解描述，声明式定义。明确代码含义。
     * <p>
     * 如果请求参数是表单参数，则必须提供注解@RequestParam描述，且属性value必须定义，代表请求参数命名。
     * 注解value属性值，就是请求参数名称。
     * 方法参数值，就是请求参数值。
     * 未提供@RequestParam注解value属性，异常描述：RequestParam.value() was empty on parameter ?
     * 为提供@RequestParam注解，且方法参数多于1，异常描述：Method has too many Body parameters
     */
    @GetMapping("/getArgs")
    String getArgs(@RequestParam("name") String name, @RequestParam("age") int age);

    /**
     * 方法名称自定义。
     * 返回值类型，代表远程服务的返回值类型。
     * 参数表，代表远程服务需要的请求参数
     * 注解GetMapping，代表本次请求是一个GET请求。
     * 注解GetMapping的属性value，代表本次请求要访问的地址是什么。
     * 本次请求是： http://ribbon-app-service/getNoArgs  get请求  远程返回字符串。
     *
     * @return
     */
    @GetMapping("/getNoArgs")
    String suibian();
}
